package com.example.train.controller;

import cn.hutool.core.collection.CollUtil;
import com.example.train.common.base.model.ResponseBase;
import com.example.train.common.base.model.ResponsePage;
import com.example.train.common.config.security.utils.JwtTokenUtil;
import com.example.train.common.constant.SysConstant;
import com.example.train.model.request.SysAdminLoginRequest;
import com.example.train.model.SysAdmin;
import com.example.train.model.SysAdminRoleRelation;
import com.example.train.model.vo.SysAdminVO;
import com.example.train.model.vo.SysRoleVO;
import com.example.train.service.SysAdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/admin")
public class SysAdminController {

    @Resource
    private SysAdminService sysAdminService;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.tokenHeader}")
    private String tokenHeader;

    @PostMapping("/login")
    public ResponseBase<SysAdminVO> login(@RequestBody @Valid SysAdminLoginRequest sysAdminLoginRequest,
                                          HttpServletResponse response) {
        try {
            SysAdmin sysAdmin = sysAdminService.login(sysAdminLoginRequest);

            SysAdminVO sysAdminVO = new SysAdminVO();
            BeanUtils.copyProperties(sysAdmin, sysAdminVO);
            List<SysRoleVO> roleVOs = sysAdmin.getRoles().stream().map(l -> {
                SysRoleVO roleVO = new SysRoleVO();
                BeanUtils.copyProperties(l, roleVO);
                return roleVO;
            }).collect(Collectors.toList());
            sysAdminVO.setRoles(roleVOs);
            String token = jwtTokenUtil.generateToken(sysAdmin.getUsername(), sysAdmin.getTokenSalt());
            response.setHeader(tokenHeader, token);
            return ResponseBase.success(sysAdminVO);
        } catch (AuthenticationException e) {
            return ResponseBase.failed(e.getMessage());
        }
    }

    @PostMapping("/add")
    public ResponseBase<Integer> register(@RequestBody @Valid SysAdmin sysAdmin) {

        String pwd = sysAdmin.getPassword();
        if (!pwd.matches(SysConstant.REGEX_PASSWORD_STRONG)) {
            return ResponseBase.failed("密码不符合规范");
        }

        Integer insert = sysAdminService.insert(sysAdmin);
        if (insert == null) {
            return ResponseBase.failed("用户已存在");
        }
        return ResponseBase.success(insert);
    }

    @PutMapping
    public ResponseBase<Integer> update(@RequestBody SysAdmin sysAdmin) {
        int i = sysAdminService.updateByPrimaryKeySelective(sysAdmin);
        if (i == 0) {
            return ResponseBase.failed("不存在该数据");
        } else {
            return ResponseBase.success(i);
        }
    }

    @PostMapping("/updateAdminRole")
    public ResponseBase updateAdminRole(@RequestBody List<SysAdminRoleRelation> param) throws Exception {
        if (CollUtil.isEmpty(param)) {
            return ResponseBase.failed();
        }
        int i = sysAdminService.updateMultiAdminRole(param);
        return ResponseBase.success(i);
    }

    @DeleteMapping("/{id}")
    public ResponseBase<Integer> delete(@PathVariable Long id) {
        int i = sysAdminService.deleteByPrimaryKey(id);
        if (i == 0) {
            return ResponseBase.failed("不存在该数据");
        } else {
            return ResponseBase.success(i);
        }
    }

    @GetMapping("/{id}")
    public ResponseBase<SysAdmin> get(@PathVariable Long id) {
        SysAdmin sysAdmin = sysAdminService.selectByPrimaryKey(id, true);
        if (sysAdmin == null) {
            return ResponseBase.failed("不存在该数据");
        }
        return ResponseBase.success(sysAdmin);
    }

    @GetMapping("/list")
    public ResponseBase<ResponsePage<SysAdminVO>> list(@RequestParam(defaultValue = "1") int pageNum,
                                                       @RequestParam(defaultValue = "${settings.pageHelper.pageSize}") int pageSize) {
        List<SysAdmin> list = sysAdminService.selectAll(pageNum, pageSize);
        ResponsePage<SysAdmin> restPage = ResponsePage.restPage(list);

        List<SysAdminVO> collect = list.stream().map(l -> {
            SysAdminVO adminVO = new SysAdminVO();
            BeanUtils.copyProperties(l, adminVO);

            List<SysRoleVO> roleVOS = l.getRoles().stream().map(r -> {
                SysRoleVO roleVO = new SysRoleVO();
                BeanUtils.copyProperties(r, roleVO);
                return roleVO;
            }).collect(Collectors.toList());

            adminVO.setRoles(roleVOS);
            return adminVO;
        }).collect(Collectors.toList());

        ResponsePage<SysAdminVO> restPageVO = new ResponsePage<>();
        restPageVO.setPageNum(restPage.getPageNum());
        restPageVO.setPageSize(restPage.getPageSize());
        restPageVO.setTotal(restPage.getTotal());
        restPageVO.setTotalPage(restPage.getTotalPage());
        restPageVO.setList(collect);

        return ResponseBase.success(restPageVO);
    }
}
